home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / Mail / edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-08  |  4.1 KB  |  196 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "%W% (Berkeley) %G%";
  20. #endif /* not lint */
  21.  
  22. #include "rcv.h"
  23. #include <sys/stat.h>
  24.  
  25. /*
  26.  * Mail -- a mail program
  27.  *
  28.  * Perform message editing functions.
  29.  */
  30.  
  31. /*
  32.  * Edit a message list.
  33.  */
  34.  
  35. editor(msgvec)
  36.     int *msgvec;
  37. {
  38.  
  39.     return edit1(msgvec, 'e');
  40. }
  41.  
  42. /*
  43.  * Invoke the visual editor on a message list.
  44.  */
  45.  
  46. visual(msgvec)
  47.     int *msgvec;
  48. {
  49.  
  50.     return edit1(msgvec, 'v');
  51. }
  52.  
  53. /*
  54.  * Edit a message by writing the message into a funnily-named file
  55.  * (which should not exist) and forking an editor on it.
  56.  * We get the editor from the stuff above.
  57.  */
  58. edit1(msgvec, type)
  59.     int *msgvec;
  60.     char type;
  61. {
  62.     register int c;
  63.     int i;
  64.     FILE *fp;
  65.     register struct message *mp;
  66.     off_t size;
  67.  
  68.     /*
  69.      * Deal with each message to be edited . . .
  70.      */
  71.     for (i = 0; msgvec[i] && i < msgCount; i++) {
  72.         int (*sigint)();
  73.  
  74.         if (i > 0) {
  75.             char buf[100];
  76.             char *p;
  77.  
  78.             printf("Edit message %d [ynq]? ", msgvec[i]);
  79.             if (fgets(buf, sizeof buf, stdin) == 0)
  80.                 break;
  81.             for (p = buf; *p == ' ' || *p == '\t'; p++)
  82.                 ;
  83.             if (*p == 'q')
  84.                 break;
  85.             if (*p == 'n')
  86.                 continue;
  87.         }
  88.         dot = mp = &message[msgvec[i] - 1];
  89.         touch(mp);
  90.         sigint = signal(SIGINT, SIG_IGN);
  91.         fp = run_editor(setinput(mp), mp->m_size, type, readonly);
  92.         if (fp != NULL) {
  93.             (void) fseek(otf, (long) 0, 2);
  94.             size = ftell(otf);
  95.             mp->m_block = blockof(size);
  96.             mp->m_offset = offsetof(size);
  97.             mp->m_size = fsize(fp);
  98.             mp->m_lines = 0;
  99.             mp->m_flag |= MODIFY;
  100.             rewind(fp);
  101.             while ((c = getc(fp)) != EOF) {
  102.                 if (c == '\n')
  103.                     mp->m_lines++;
  104.                 if (putc(c, otf) == EOF)
  105.                     break;
  106.             }
  107.             if (ferror(otf))
  108.                 perror("/tmp");
  109.             (void) fclose(fp);
  110.         }
  111.         (void) signal(SIGINT, sigint);
  112.     }
  113.     return 0;
  114. }
  115.  
  116. /*
  117.  * Run an editor on the file at "fpp" of "size" bytes,
  118.  * and return a new file pointer.
  119.  * Signals must be handled by the caller.
  120.  * "Type" is 'e' for EDITOR, 'v' for VISUAL.
  121.  */
  122. FILE *
  123. run_editor(fp, size, type, readonly)
  124.     register FILE *fp;
  125.     off_t size;
  126.     char type;
  127. {
  128.     register FILE *nf = NULL;
  129.     register int t;
  130.     time_t modtime;
  131.     char *edit;
  132.     struct stat statb;
  133.     extern char tempEdit[];
  134.  
  135.     if ((t = creat(tempEdit, readonly ? 0400 : 0600)) < 0) {
  136.         perror(tempEdit);
  137.         goto out;
  138.     }
  139.     if ((nf = fdopen(t, "w")) == NULL) {
  140.         perror(tempEdit);
  141.         (void) unlink(tempEdit);
  142.         goto out;
  143.     }
  144.     if (size >= 0)
  145.         while (--size >= 0 && (t = getc(fp)) != EOF)
  146.             (void) putc(t, nf);
  147.     else
  148.         while ((t = getc(fp)) != EOF)
  149.             (void) putc(t, nf);
  150.     (void) fflush(nf);
  151.     if (fstat(fileno(nf), &statb) < 0)
  152.         modtime = 0;
  153.     else
  154.         modtime = statb.st_mtime;
  155.     if (ferror(nf) || fclose(nf) < 0) {
  156.         perror(tempEdit);
  157.         (void) unlink(tempEdit);
  158.         nf = NULL;
  159.         goto out;
  160.     }
  161.     nf = NULL;
  162.     if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NOSTR)
  163.         edit = type == 'e' ? EDITOR : VISUAL;
  164.     if (run_command(edit, 0, -1, -1, tempEdit, NOSTR) < 0) {
  165.         (void) unlink(tempEdit);
  166.         goto out;
  167.     }
  168.     /*
  169.      * If in read only mode or file unchanged, just remove the editor
  170.      * temporary and return.
  171.      */
  172.     if (readonly) {
  173.         (void) unlink(tempEdit);
  174.         goto out;
  175.     }
  176.     if (stat(tempEdit, &statb) < 0) {
  177.         perror(tempEdit);
  178.         goto out;
  179.     }
  180.     if (modtime == statb.st_mtime) {
  181.         (void) unlink(tempEdit);
  182.         goto out;
  183.     }
  184.     /*
  185.      * Now switch to new file.
  186.      */
  187.     if ((nf = fopen(tempEdit, "a+")) == NULL) {
  188.         perror(tempEdit);
  189.         (void) unlink(tempEdit);
  190.         goto out;
  191.     }
  192.     (void) unlink(tempEdit);
  193. out:
  194.     return nf;
  195. }
  196.